home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / util / bsindex1 / part01 / src / checkfiles.c < prev    next >
C/C++ Source or Header  |  1990-02-02  |  7KB  |  257 lines

  1. /*
  2.  * CHECKFILES.C
  3.  *
  4.  * This module contains routines to read in the disk directory, search
  5.  * the file database for each filename found to see if it matches, etc.
  6.  *
  7.  */
  8.  
  9. #ifndef LATTICE_50
  10. #include "system.h"
  11. #endif
  12. #include "bbsindex.h"
  13.  
  14. /*
  15.  *        addunknown()
  16.  *        ------------
  17.  *        Adds a new entry to the list of unknown files found. If necessary,
  18.  *        more memory will be allocated to hold the new entry.
  19.  */
  20. int addunknown(name, size, date, dirnum)
  21. char *name;
  22. long size;
  23. int date, dirnum;
  24. {
  25.     static DIRENTRY *dirbase, *dir;
  26.  
  27.     if (numdirentries >= MAXDIRENT) {
  28.         scripterror("directory table full. Skipping rest of files\n");
  29.         return (FALSE);
  30.     }
  31.     if ((numdirentries % DIRFRAG) == 0)     /* Allocate new block */
  32.         dirbase = mymalloc(DIRENTRYSIZE * DIRFRAG);
  33.  
  34.     dir = &dirbase[numdirentries % DIRFRAG];
  35.  
  36.     strcpy(dir->name, name);
  37.     dir->size    = size;
  38.     dir->date    = date;
  39.     dir->dirnum    = dirnum;
  40.  
  41.     direntries[numdirentries++] = dir;
  42.     return (TRUE);
  43. }
  44.  
  45. /*
  46.  *        find()
  47.  *        ------
  48.  *        Does a binary search of the file records looking for the specified
  49.  *        filename. Returns pointer to the file record if found, NULL if not
  50.  *        found.
  51.  */
  52. UDHEAD *find(name)
  53. char *name;
  54. {
  55.     long low = 0, high = numrecs -1;
  56.     long mid;
  57.     int cmp;
  58.  
  59.     while (high >= low) {
  60.         mid = (low + high) / 2;
  61.         cmp = stricmp(ptrblock[mid]->disk_name, name);
  62.         if (!cmp && ptrblock[mid]->type == 0)        /* Found match */
  63.             return (ptrblock[mid]);
  64.         if (cmp > 0)                        /* Too far ahead, go backwards */
  65.             high = mid-1;
  66.         else                                /* Too far below, go forwards */
  67.             low  = mid+1;
  68.     }
  69.     return (NULL);
  70. }
  71.  
  72. /*
  73.  *        scandir()
  74.  *        ---------
  75.  *        Scans directory, adding the files found either to the 'unknown'
  76.  *        list or updating the pointers in the main file database appropriately.
  77.  */
  78. int scandir(dirname, dirnum)
  79. char *dirname;
  80. int dirnum;
  81. {
  82.     UDHEAD *f;
  83.     struct tm *filedate;
  84.     int bbspcdate;
  85.  
  86.     dirlock = Lock(dirname, ACCESS_READ);
  87.     if (dirlock == NULL) {
  88.         scripterror("can't find directory ");
  89.         print2(dirname, ", skipping\n");
  90.         return (TRUE);
  91.     }
  92.  
  93.     if (!Examine(dirlock, fib)) {
  94.         scripterror("can't examine directory ");
  95.         print2(dirname, ", skipping\n");
  96.         UnLock(dirlock);
  97.         dirlock = NULL;
  98.         return (TRUE);
  99.     }
  100.  
  101.     while (ExNext(dirlock, fib)) {
  102.         chkabort();
  103.         if (fib->fib_DirEntryType > 0)    /* Skip over directories */
  104.             continue;
  105.         if (f = find(fib->fib_FileName)) {
  106.             f->online = 1;
  107.             f->valid = (fib->fib_Size == f->length);
  108.             f->dirnum = dirnum;
  109.         } else {
  110.             /*
  111.              *        Convert AmigaDOS date (# days since 1/1/78, # mins
  112.              *        since midnight) into ANSI date (# seconds since 1/1/70)
  113.              *        then convert that into BBS-PC! format.
  114.              */
  115.             long ansidate;
  116.             ansidate = (fib->fib_Date.ds_Days + (365 * 8) + 2) * 86400;
  117.             filedate = gmtime(&ansidate);
  118.             bbspcdate = (((filedate->tm_year * 13) +
  119.                           (filedate->tm_mon+1)) * 32) +
  120.                            filedate->tm_mday;
  121.             if (!addunknown(fib->fib_FileName, fib->fib_Size, bbspcdate,
  122.                                                                     dirnum)) {
  123.                 UnLock(dirlock);
  124.                 dirlock = NULL;
  125.                 return (FALSE);
  126.             }
  127.  
  128.         }
  129.     }
  130.     if (IoErr() != ERROR_NO_MORE_ENTRIES) {
  131.         scripterror("error reading directory ");
  132.         print2(dirname, ", skipping\n");
  133.     }
  134.     UnLock(dirlock);
  135.     dirlock = NULL;
  136.     return (TRUE);
  137. }
  138.  
  139. /*
  140.  *        diskcmp()
  141.  *        ---------
  142.  *        Compares the disk filenames of two file headers, and returns true
  143.  *        if they are equal. Used by the sort routine in check_files().
  144.  */
  145. int diskcmp(f1,f2)
  146. UDHEAD **f1, **f2;
  147. {
  148.     return (stricmp((*f1)->disk_name, (*f2)->disk_name));
  149. }
  150.  
  151. /*
  152.  *        com_checkfiles()
  153.  *        ----------------
  154.  *        This command scans the file directories specified on the command
  155.  *        line (or if none, then using those specified in the CFGINFO.DAT
  156.  *        file). Each file in the catalogue is searched for in the file
  157.  *        catalogue, and those that are found are marked as "Online"; if
  158.  *        the disk filesize matches the catalogue filesize, then their
  159.  *        "valid" flag is also set. Files which are not found are stored
  160.  *        in a seperate array, which can be printed with the FOREIGN command.
  161.  *        After this, any other files listed in the IGNORE list are also marked
  162.  *        as valid.
  163.  *
  164.  *        Note that before the scan, the files are sorted into alphabetical
  165.  *        order, by diskname, to allow a binary search to be done. Afterwards,
  166.  *        if this disrupted a previous sorting order, they are sorted back
  167.  *        to their original state.
  168.  */
  169. void com_checkfiles()
  170. {
  171.     int dirnum;
  172.     IGNORE *ig;
  173.     UDHEAD *f;
  174.  
  175.     if (checkfiles)
  176.         return;
  177.  
  178.     CHECKDATABASE();
  179.     qsort(ptrblock, numrecs, sizeof(UDHEAD *), diskcmp);
  180.     if (compos >= comlen) {
  181.         readconfigfile();
  182.         for (dirnum = 0; dirnum < NUM_SECT && dirnames[dirnum][0]; dirnum++) {
  183.             chkabort();
  184.             if (!scandir(dirnames[dirnum], dirnum))
  185.                 break;
  186.         }
  187.     } else {
  188.         for (dirnum = 0; dirnum < NUM_SECT; dirnum++) {
  189.             if (compos >= comlen)
  190.                 break;
  191.             strcpy(dirnames[dirnum], getstring());
  192.             chkabort();
  193.             if (!scandir(dirnames[dirnum], dirnum))
  194.                 break;
  195.         }
  196.     }
  197.     /*
  198.      *        Now mark any "ignored" files as valid.
  199.      */
  200.     for (ig = firstignore; ig; ig = ig->next) {
  201.         if (f = find(ig->name))
  202.             f->valid = 1;
  203.     }
  204.     chkabort();
  205.     if (sorted)
  206.         qsort(ptrblock, numrecs, sizeof(UDHEAD *), sortcmp);
  207.     checkfiles = TRUE;
  208. }
  209.  
  210. /*
  211.  *        com_foreign()
  212.  *        -------------
  213.  *        This command prints out the list of foreign files, i.e. files
  214.  *        not in the catalogue, using the format string setup with
  215.  *        FORMAT. Not all fields are valid.
  216.  */
  217. void com_foreign()
  218. {
  219.     /*
  220.      *        Standard file header template for foreign files.
  221.      *        Note file[] is an array, so we can say file->x instead of file.x
  222.      */
  223.     static UDHEAD file[1] = {{
  224.         0,                        /* Record type (== valid)                */
  225.         1, 1, 1, 1,             /* Local, Binary, Valid and Online :-)    */
  226.         0,                        /* Directory number is set later        */
  227.         "",                        /* Catalogue filename, filled in later    */
  228.         0,                        /* Date is set later                    */
  229.         0, 0, 0,                /* Section 0, Directory 0, no accesses    */
  230.         0,                        /* Length is set later                    */
  231.         "",                        /* Disk name is set later                */
  232.         "AmigaDos",                /* The file owner                        */
  233.         "Directory = ",            /* File comment, set later                */
  234.     }};
  235.  
  236.     int i;
  237.  
  238.     if (!checkfiles) {
  239.         scripterror("can't do FOREIGN before CHECKFILES\n");
  240.         Cleanup(10);
  241.     }
  242.  
  243.     for (i = 0; i < numdirentries; i++) {
  244.         chkabort();
  245.         /* Setup actual file parameters for format() */
  246.         strcpy(file->disk_name, direntries[i]->name);
  247.         strncpy(file->cat_name, direntries[i]->name, CAT_LEN);
  248.         strncpy(file->desc+12, dirnames[direntries[i]->dirnum], DESC_LEN-12);
  249.         file->desc[DESC_LEN] = CHAR_NULL;
  250.         file->length    = direntries[i]->size;
  251.         file->date        = direntries[i]->date;
  252.         file->dirnum    = direntries[i]->dirnum;
  253.         format(out, MAXOUT, formatstring, file, checkfiles);
  254.         putstring(out);
  255.     }
  256. }
  257.